package utils;

import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.WeakHashMap;

/**
 * Created by wuzhao on 2017/8/17 0017.
 */
public class IdMutexProvider {

    private static final Map<Mutex,WeakReference> mutexMap = new WeakHashMap();

    /**Get a mutex object for the given (non-null) id.*/
    public static Mutex getMutex(String id) {
        if(id == null) {
            throw new NullPointerException();
        }

        Mutex key = new MutexImpl(id);
        synchronized(mutexMap) {
            WeakReference ref = mutexMap.get(key);
            if(ref==null) {
                mutexMap.put(key, new WeakReference(key));
                return key;
            }
            Mutex mutex = (Mutex) ref.get();
            if(mutex==null) {
                mutexMap.put(key, new WeakReference(key));
                return key;
            }
            return mutex;
        }
    }

    /**Get the number of mutex objects being held*/
    public int getMutexCount() {
        synchronized(mutexMap) {
            return mutexMap.size();
        }
    }

    public interface Mutex {}

    private static class MutexImpl implements Mutex {
        private final String id;
        protected MutexImpl(String id) {
            this.id = id;
        }
        public boolean equals(Object o) {
            if(o==null) {
                return false;
            }
            return this.id.equals(o.toString());
        }
        public int hashCode() {
            return id.hashCode();
        }
        public String toString() {
            return id;
        }
    }

    public static void main(String[] args) {
        String aa = "武昭";
        String bb = "武昭";
        IdMutexProvider.Mutex m1a = IdMutexProvider.getMutex(aa);
        IdMutexProvider.Mutex m1a2 = IdMutexProvider.getMutex(bb);
        System.out.printf("==="+(m1a == m1a2));
    }
}
